/*
Copyleft 2006 by T.S.Yo
*/


package exp.util;
import java.io.*;
import java.util.*;
import ec.*;
import ec.util.*;
import ec.simple.*;

/* 
 * MyExpOutput.java
 * 
 * Created: 2007.01.19
 * By: T.S.Yo
 */

/**
 * MyExpOutput make customized output:
 * 
 * - read in two file names, one for subjective fitness, the other for objective
 * - each line in each file: generation number and fitness values for each population
 *
 * @author T.S.Yo
 * @version 1.0 
 */

public class MyExpOutput
{
    // Define parameter names
    public static final String BASE  = "myoutput";
    public static final String OBJF  = "obj";
    public static final String SUBJF = "subj";
    // File names for output
    public String objFile;
    public String subjFile;
    // Output stream
    PrintWriter outo;
    PrintWriter outs;

    
    // Constructor
    public MyExpOutput(final EvolutionState state)
    {
        // Read in parameters
        Parameter base = new Parameter(BASE);
        objFile = state.parameters.getString(base.push(OBJF),null);
        if( objFile == null )
            state.output.fatal( "Parameter missing, file name for objective fitness.", base.push(OBJF) );
        subjFile = state.parameters.getString(base.push(SUBJF),null);
        if( subjFile == null )
            state.output.fatal( "Parameter missing, file name for subjective fitness.", base.push(SUBJF) );
            
        // Initialize file writers
        // Define whether to open new files or to append
        boolean appFlag = (state.generation!=0);
        // Open output file for objective-fitness
        try {  // Create the output stream.
              outo = new PrintWriter(new FileWriter(objFile,appFlag));
        } catch (java.io.IOException e) { 
            System.out.println("Can't open file "+objFile+"!");
            System.out.println("Error: " + e);
            return;        // End the program.
        }
        // Open output file for subjective-fitness
        try {  // Create the output stream.
              outs = new PrintWriter(new FileWriter(subjFile,appFlag));
        } catch (java.io.IOException e) { 
            System.out.println("Can't open file "+subjFile+"!");
            System.out.println("Error: " + e);
            return;        // End the program.
        }
    }
    
    // Output both subjective and objective fitness
    public void printFit(final EvolutionState state, 
                         final Population pop,
                         final float[] objf)
    {
        // Retrieve subjective fitness
        float[] subjf = new float[objf.length];
        for (int j = 0; j<objf.length; j++)
        {
            subjf[j] = ((SimpleFitness)(pop.subpops[1].individuals[j].fitness)).fitness();
        }
        // Output
        outo.println(state.generation+","+floatVectorToString(objf));
        outs.println(state.generation+","+floatVectorToString(subjf));
        // Close
        outo.close();
        outs.close();
    }
    
    // Output only subjective fitness: non-coevolution
    public void printFit(final EvolutionState state, 
                         final Population pop)
    {
        // Retrieve subjective fitness
        int nsol = pop.subpops[0].individuals.length;
        float[] subjf = new float[nsol];
        for (int j = 0; j<nsol; j++)
        {
            subjf[j] = ((SimpleFitness)(pop.subpops[0].individuals[j].fitness)).fitness();
        }
        // Output
        outs.println(state.generation+","+floatVectorToString(subjf));
        // Close
        outo.close();
        outs.close();
    }
    
    // Convert array to string
    public String floatVectorToString(final float[] fv)
    {
        String out = new String();
        out = out + fv[0];
        for(int i=1; i<fv.length; i++)
        {
            out = out + "," + fv[i];
        }
        return out;
    }
}
